import * as usersService from '../services/users';

//lz: reducers 对state的操作,由action触发 : action名(state, action) => newState 
//    effects  处理异步操作和业务逻辑,定义action : function(payload:传递的参数,执行的操作方法){}
//    subscriptions 监听数据
export default {
  namespace: 'users', //namespace: model 的命名空间(唯一性),不支持多层命名空间
  state: { //state: 初始值，优先级低于传给 dva() 的 opts.initialState
    list: [],
    total: null,
    page: null,
  },
  reducers: { //reducers: 尽量只做state的数据返回 ,以 key/value 格式定义 reducer。用于处理同步操作，唯一可以修改 state 的地方。由 action 触发。
    save(state, { payload: { data: list, total, page } }) { //reducer 是一个函数，接受 state 和 action，返回老的或新的 state。格式为 (state, action) => newState
      return { ...state, list, total, page }; //lz: 保存数据到 state
    },
  },
  effects: { //effects: 以 key/value 格式定义 effect。用于处理异步操作和业务逻辑，不直接修改 state。由 action 触发，可以触发 action，可以和服务器交互，可以获取全局 state 的数据等等。
    *fetch({ payload: { page = 1 } }, { call, put }) { 
      const { data, headers } = yield call(usersService.fetch, { page });
      yield put({ //put :用于触发 action ; call :用于调用异步逻辑 ; select : 从state中获取相关的数据; take : 获取发送的数据
        type: 'save',
        payload: {
          data,
          total: parseInt(headers['x-total-count'], 10),
          page: parseInt(page, 10),
        },
      });
    },
    *remove({ payload: id }, { call, put }) {
      yield call(usersService.remove, id); // lz: yield:暂停功能, 异步->同步
      yield put({ type: 'reload' }); 
    },
    *patch({ payload: { id, values } }, { call, put }) {
      yield call(usersService.patch, id, values); //lz: call:有阻塞地调用 saga 或者返回 promise 的函数，只在触发某个动作。
      yield put({ type: 'reload' }); //lz: put:触发某个action， 作用和dispatch相同 ; type:定义的action ,payload:传递的参数
    },
    *create({ payload: values }, { call, put }) { //lz: 调用异步逻辑接口获取数据 -> 触发reload action -> 更新state
      yield call(usersService.create, values);
      yield put({ type: 'reload' });
    },
    *reload(action, { put, select }) { //lz : reload action
      const page = yield select(state => state.users.page); //lz: select:从state中获取相关的数据
      yield put({ type: 'fetch', payload: { page } });
    },
  },
  subscriptions: { //subscriptions: 以 key/value 格式定义 subscription。subscription 是订阅，用于订阅一个数据源，然后根据需要 dispatch 相应的 action。在 app.start() 时被执行，数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等。
    setup({ dispatch, history }) {
      return history.listen(({ pathname, query }) => {  // lz:监听 history 变化，当进入 `/users` 时触发 `fetch` action
        if (pathname === '/users') {
          dispatch({ type: 'fetch', payload: query });
        }
      });
    },
  },
};
